package com.distortiongames.level27.components.render
{
	import com.distortiongames.level27.generation.Element;
	import com.distortiongames.level27.generation.Map;
	import com.distortiongames.level27.generation.Point;
	import com.distortiongames.level27.generation.Room;
	import com.distortiongames.level27.math.Vector2D;
	import com.pblabs.core.PBComponent;
	import flash.display.CapsStyle;
	import flash.events.MouseEvent;
	
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	
	public class TileRenderer extends PBComponent
	{
		public static const ROOM_COLOR:uint = 0x58595B;
		public static const WIDTH:Number = 11, HEIGHT:Number = 11, CORRIDOR_THICKNESS:Number = 3;
		public var sprite:Sprite = new Sprite();
		
		protected var _position:Point = new Point();
		protected var _value:int = 0;
		protected var _map:Map = null;
		protected var _revealed:Boolean = false;
		protected var _visible:Boolean = false;
		public var room:Room = null;
		
		protected var hovered:Boolean = false;
		
		[Inject]
		public var stage:Stage;
		
		[Inject]
		public var canvas:Sprite;
		
		public function set position(value:Point):void
		{
			_position.x = value.x;
			_position.y = value.y;
			
			sprite.x = position.x * WIDTH;
			sprite.y = position.y * HEIGHT;
		}
		
		public function get position():Point
		{
			return _position;
		}
		
		public function set value(value:int):void
		{
			var tempValue:int = _value;
			_value = value;
			if (value != 0 && tempValue != _value)
				createSprite();
		}
		
		public function get value():int
		{
			return _value;
		}
		
		public function set map(value:Map):void
		{
			_map = value;
		}
		
		public function get map():Map
		{
			return _map;
		}
		
		public function get revealed():Boolean
		{
			return _revealed;
		}
		
		public function set revealed(value:Boolean):void
		{
			_revealed = value;
			createSprite();
		}
		
		public function get visible():Boolean
		{
			return _visible;
		}
		
		public function set visible(value:Boolean):void
		{
			_visible = value;
			createSprite();
		}
		
		protected override function onAdd():void
		{
			super.onAdd();
			stage.addEventListener(Event.ENTER_FRAME, onFrame);
		
		}
		
		protected override function onRemove():void
		{
			canvas.removeChild(sprite);
			stage.removeEventListener(Event.ENTER_FRAME, onFrame);
			
			super.onRemove();
		}
		
		public function onFrame(e:*):void
		{
			applyBindings();
		}
		
		public function onHover(e:MouseEvent):void
		{
			hovered = true;
			createSprite();
		}
		
		public function onExit(e:MouseEvent):void
		{
			hovered = false;
			createSprite();
		}
		
		private function createSprite():void
		{
			sprite.graphics.clear();
			if (visible)
			{
				if (sprite.parent != null)
				{
					canvas.removeChild(sprite);
					sprite.removeEventListener(MouseEvent.MOUSE_OVER, onHover);
					sprite.removeEventListener(MouseEvent.MOUSE_OUT, onExit);
				}
				sprite.x = position.x * WIDTH;
				sprite.y = position.y * HEIGHT;
				if (_value >= Map.ROOM_START)
				{
					if (room.element == Element.NEUTRAL || !revealed)
					{
						drawRoom();
					}
					else if (room.element == Element.WATER)
					{
						drawElementRoom(0x27AAE1);
					}
					else if (room.element == Element.FIRE)
					{
						drawElementRoom(0xF15A29);
					}
					else if (room.element == Element.EARTH)
					{
						drawElementRoom(0x91A23D);
					}
					else if (room.element == Element.WIND)
					{
						drawElementRoom(0xFFFF84);
					}
				}
				else
				{
					switch (_value)
					{
						case Map.START: 
							sprite.graphics.lineStyle(CORRIDOR_THICKNESS, hovered ? 0x707070 : 0xC4DF9B, 1, false, "", CapsStyle.NONE);
							drawEnds();
							//sprite.graphics.beginFill(hovered ? 0x707070 : 0xC4DF9B);
							//sprite.graphics.drawRoundRect(0, 0, WIDTH, HEIGHT, WIDTH/2, HEIGHT/2);
							//sprite.graphics.endFill();
							break;
						case Map.END: 
							sprite.graphics.lineStyle(CORRIDOR_THICKNESS, hovered ? 0x707070 : 0xFF4848, 1, false, "", CapsStyle.NONE);
							drawEnds();
							//sprite.graphics.beginFill(hovered ? 0x707070 : 0xFF4848);
							//sprite.graphics.drawRoundRect(0, 0, WIDTH, HEIGHT, WIDTH / 2, HEIGHT / 2);
							//sprite.graphics.endFill();
							break;
						case Map.CORRIDOR: 
							sprite.graphics.lineStyle(CORRIDOR_THICKNESS, hovered ? 0x707070 : 0x6D6E71, 1, false, "", CapsStyle.NONE);
							drawCorridor();
							break;
					}
				}
				canvas.addChild(sprite);
				sprite.addEventListener(MouseEvent.MOUSE_OVER, onHover);
				sprite.addEventListener(MouseEvent.MOUSE_OUT, onExit);
			}
		}
		
		private function drawRoom():void
		{
			sprite.graphics.beginFill(hovered ? 0x707070 : ROOM_COLOR);
			sprite.graphics.drawRoundRect(0, 0, WIDTH, HEIGHT, WIDTH / 2, HEIGHT / 2);
			sprite.graphics.endFill(); //FF4848
		}
		
		private function drawElementRoom(fill:int):void
		{
			drawRoom();
			sprite.graphics.beginFill(fill);
			sprite.graphics.drawRoundRect(2, 2, WIDTH - 4, HEIGHT - 4, WIDTH / 2, HEIGHT / 2);
			sprite.graphics.endFill();
		}
		
		private function drawCorridor():void
		{
			var north:int = map.getNorthValue(_position);
			var south:int = map.getSouthValue(_position);
			var east:int = map.getEastValue(_position);
			var west:int = map.getWestValue(_position);
			var surrounding:int = map.getNumberOfSurroundingTiles(_position);
			if (surrounding == 1)
			{
				
				if (north != 0)
				{
					sprite.graphics.moveTo(WIDTH / 2, 0);
					sprite.graphics.lineTo(WIDTH / 2, HEIGHT / 2);
				}
				if (south != 0)
				{
					sprite.graphics.moveTo(WIDTH / 2, 0 + HEIGHT);
					sprite.graphics.lineTo(WIDTH / 2, HEIGHT / 2);
				}
				if (east != 0)
				{
					sprite.graphics.moveTo(WIDTH, 0 + HEIGHT / 2);
					sprite.graphics.lineTo(WIDTH / 2, HEIGHT / 2);
				}
				if (west != 0)
				{
					sprite.graphics.moveTo(0, HEIGHT / 2);
					sprite.graphics.lineTo(WIDTH / 2, HEIGHT / 2);
				}
			}
			else
			{
				if (north && south)
				{
					sprite.graphics.moveTo(WIDTH / 2, 0);
					sprite.graphics.lineTo(WIDTH / 2, HEIGHT);
				}
				if (west && east)
				{
					sprite.graphics.moveTo(0, HEIGHT / 2);
					sprite.graphics.lineTo(WIDTH, HEIGHT / 2);
				}
				if (north && east)
				{
					sprite.graphics.moveTo(WIDTH / 2, 0);
					sprite.graphics.curveTo(WIDTH / 2, HEIGHT / 2, WIDTH, HEIGHT / 2);
				}
				if (east && south)
				{
					sprite.graphics.moveTo(WIDTH, HEIGHT / 2);
					sprite.graphics.curveTo(WIDTH / 2, HEIGHT / 2, WIDTH / 2, HEIGHT);
				}
				if (south && west)
				{
					sprite.graphics.moveTo(WIDTH / 2, HEIGHT);
					sprite.graphics.curveTo(WIDTH / 2, HEIGHT / 2, 0, HEIGHT / 2);
				}
				if (west && north)
				{
					sprite.graphics.moveTo(0, HEIGHT / 2);
					sprite.graphics.curveTo(WIDTH / 2, HEIGHT / 2, WIDTH / 2, 0);
				}
			}
		}
		
		private function drawEnds():void
		{
			var north:int = map.getNorthValue(_position);
			var south:int = map.getSouthValue(_position);
			var east:int = map.getEastValue(_position);
			var west:int = map.getWestValue(_position);
			var surrounding:int = map.getNumberOfSurroundingTiles(_position);
			if (surrounding == 1)
			{
				if (north != 0)
				{
					sprite.graphics.moveTo(WIDTH / 2, 0);
					sprite.graphics.lineTo(WIDTH / 2, HEIGHT);
				}
				if (south != 0)
				{
					sprite.graphics.moveTo(WIDTH / 2, 0 + HEIGHT);
					sprite.graphics.lineTo(WIDTH / 2, 0);
				}
				if (east != 0)
				{
					sprite.graphics.moveTo(WIDTH, HEIGHT / 2);
					sprite.graphics.lineTo(0, HEIGHT / 2);
				}
				if (west != 0)
				{
					sprite.graphics.moveTo(0, HEIGHT / 2);
					sprite.graphics.lineTo(WIDTH, HEIGHT / 2);
				}
			}
			else
			{
				if (north && south)
				{
					sprite.graphics.moveTo(WIDTH / 2, 0);
					sprite.graphics.lineTo(WIDTH / 2, HEIGHT);
				}
				if (west && east)
				{
					sprite.graphics.moveTo(0, HEIGHT / 2);
					sprite.graphics.lineTo(WIDTH, HEIGHT / 2);
				}
				if (north && east)
				{
					sprite.graphics.moveTo(WIDTH / 2, 0);
					sprite.graphics.curveTo(WIDTH / 2, HEIGHT / 2, WIDTH, HEIGHT / 2);
				}
				if (east && south)
				{
					sprite.graphics.moveTo(WIDTH, HEIGHT / 2);
					sprite.graphics.curveTo(WIDTH / 2, HEIGHT / 2, WIDTH / 2, HEIGHT);
				}
				if (south && west)
				{
					sprite.graphics.moveTo(WIDTH / 2, HEIGHT);
					sprite.graphics.curveTo(WIDTH / 2, HEIGHT / 2, 0, HEIGHT / 2);
				}
				if (west && north)
				{
					sprite.graphics.moveTo(0, HEIGHT / 2);
					sprite.graphics.curveTo(WIDTH / 2, HEIGHT / 2, WIDTH / 2, 0);
				}
			}
		}
	}
}